package com.kuang.handler.jwt;

import com.kuang.common.anno.IgnoreToken;
import com.kuang.common.exception.ValidationException;
import com.kuang.utils.JsonUtil;
import com.kuang.vo.AuthResponse;
import com.kuang.vo.ResponseCode;
import com.kuang.vo.UserVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author xuke
 */
public class AuthorizationInterceptor implements HandlerInterceptor {

    private static final Logger log = LoggerFactory.getLogger(AuthorizationInterceptor.class);

    @Autowired
    private JwtService jwtService;

    @Value("${spring.profiles.active}")
    private String profiles;

    private static final String AUTH = "Authorization";
    private static final String AUTH_USERNAME = "ksd-user-name";

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 校验token
     *
     * @param request
     * @param response
     * @param object
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
        response.setContentType("application/json;charset=utf-8");
        // 如果是开发环境直接通过
        if(!StringUtils.isEmpty(profiles) && profiles.equals("dev")){
            return true;
        }
        // 2：从 http 请求头获取请求接口
        HandlerMethod handlerMethod = (HandlerMethod) object;
        Method method = handlerMethod.getMethod();
        // 3：如果一个方法加了IgnoreToken代表不需要token直接放行返回
        if (method.isAnnotationPresent(IgnoreToken.class)) {
            IgnoreToken loginToken = method.getAnnotation(IgnoreToken.class);
            if (loginToken.required()) {
                return true;
            }
        }


        //4：检查是否有IgnoreToken注释，有则跳过认证
        String username = getParam(request, AUTH_USERNAME);
        String token = getParam(request, AUTH);

        if (StringUtils.isEmpty(token)) {
            throw new ValidationException(300, "Authorization不允许为空，请重新登录!!!");
        }

        if (StringUtils.isEmpty(username)) {
            throw new ValidationException(300, "username不允许为空，请重新登录!!!");
        }

        // 开始对你token和你用户名进行token校验，如果正常直接返回，如果不正常抛出异常
        AuthResponse authResponse = jwtService.verify(token, username);
        // 如果不等于1，说明token和用户名校验失败
        if (authResponse.getCode() != 1L) {
            log.error("invalid error");
            throw new ValidationException(300, "token valid fail!!!");
        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }

    public static String getParam(HttpServletRequest request, String filedName) {
        //1 :在参数里面区获取对应filedName的值
        String param = request.getParameter(filedName);
        // 2:如果不存在
        if (StringUtils.isEmpty(param)) {
            // 3: 就请求头区获取对应filedName的值
            param = request.getHeader(filedName);
        }
        return param;
    }

}
